import { useControlController, useNamespace } from '@ibiz-template/vue3-util';
import { ref, defineComponent, PropType, VNode } from 'vue';
import {
  IDEToolbar,
  IDEToolbarItem,
  IDETBGroupItem,
  IDETBUIActionItem,
} from '@ibiz/model-core';
import {
  IControlProvider,
  IExtraButton,
  ToolbarController,
} from '@ibiz-template/runtime';
import { IBizExportExcel } from './export-excel/export-excel';
import './toolbar.scss';

const btnContent = (item: IDEToolbarItem): (string | VNode)[] => {
  const image = item.sysImage;
  const result = [];
  const ns = useNamespace('toolbar-item');
  if (item.showIcon && image) {
    result.push(
      <span class={ns.b('icon')}>
        <iBizIcon icon={image} />
      </span>,
    );
  }
  if (item.showCaption && item.caption) {
    result.push(<span class={ns.b('text')}>{item.caption}</span>);
  }
  return result;
};

export const ToolbarControl = defineComponent({
  name: 'IBizToolbarControl',
  props: {
    modelData: {
      type: Object as PropType<IDEToolbar>,
      required: true,
    },
    context: { type: Object as PropType<IContext>, required: true },
    params: { type: Object as PropType<IParams>, default: () => ({}) },
    provider: { type: Object as PropType<IControlProvider> },
    manualCalcButtonState: { type: Boolean, default: false },
  },
  setup() {
    const c = useControlController((...args) => new ToolbarController(...args));
    const ns = useNamespace(`control-${c.model.controlType!.toLowerCase()}`);

    const btnSize = ref('default');

    // 点击事件
    const handleClick = async (
      item: IDEToolbarItem,
      event: MouseEvent,
      params?: IData,
    ): Promise<void> => {
      await c.onItemClick(item, event, params);
    };

    const renderExtraButtons = (extraButtons: IExtraButton[]): VNode[] => {
      return extraButtons.map(button => {
        return (
          <div key={button.id} class={[ns.e('item')]}>
            <el-button
              title={button.tooltip}
              size={btnSize.value}
              onClick={(e: MouseEvent): Promise<void> => handleClick(button, e)}
            >
              {btnContent(button)}
            </el-button>
          </div>
        );
      });
    };

    const renderSubmenu = (item: IDETBGroupItem) => {
      return (
        <el-sub-menu
          class={ns.b('submenu')}
          index={item.id}
          title={item.tooltip}
          popper-class={ns.b('submenu-popper')}
        >
          {{
            default: () => {
              return (item as IDETBGroupItem).detoolbarItems?.map(item2 => {
                const actionId = (item2 as IDETBUIActionItem).uiactionId;
                if (
                  item2.itemType === 'SEPERATOR' ||
                  item2.itemType === 'RAWITEM'
                ) {
                  return;
                }
                if (
                  item2.itemType === 'DEUIACTION' &&
                  c.state.buttonsState[item2.id!].visible
                ) {
                  if (actionId === 'exportexcel') {
                    return (
                      <IBizExportExcel
                        class={[ns.e('menu-exportexcel')]}
                        mode='menu'
                        item={item2}
                        btnContent={btnContent}
                        size={btnSize.value}
                        controller={c}
                        onExportExcel={(e: MouseEvent, data: IData): void => {
                          handleClick(item2, e, data);
                        }}
                      ></IBizExportExcel>
                    );
                  }
                  return (
                    <el-menu-item
                      index={`menuitem${item2.id}`}
                      disabled={c.state.buttonsState[item2.id!].disabled}
                      title={item2.tooltip}
                      onClick={(e: MouseEvent): Promise<void> =>
                        handleClick(item2, e)
                      }
                    >
                      {btnContent(item2)}
                    </el-menu-item>
                  );
                }
                if (item2.itemType === 'ITEMS') {
                  return renderSubmenu(item2);
                }
                return null;
              });
            },
            title: () => {
              return <span>{btnContent(item)}</span>;
            },
          }}
        </el-sub-menu>
      );
    };

    const renderToolbarItem = (item: IDEToolbarItem): VNode | null => {
      const itemId = item.id!;
      if (item.itemType === 'SEPERATOR') {
        return (
          <div key={itemId} class={[ns.e('item'), ns.e('item-separator')]}>
            |
          </div>
        );
      }
      if (item.itemType === 'RAWITEM') {
        return (
          <div key={itemId} class={[ns.e('item'), ns.e('item-rawitem')]}>
            {btnContent(item)}
          </div>
        );
      }
      if (
        item.itemType === 'DEUIACTION' &&
        c.state.buttonsState[itemId].visible
      ) {
        const actionId = (item as IDETBUIActionItem).uiactionId;
        if (actionId === 'exportexcel') {
          return (
            <IBizExportExcel
              class={[ns.e('item'), ns.e('item-deuiaction')]}
              item={item}
              btnContent={btnContent}
              size={btnSize.value}
              controller={c}
              onExportExcel={(e: MouseEvent, data: IData): void => {
                handleClick(item, e, data);
              }}
            ></IBizExportExcel>
          );
        }
        return (
          <div
            key={itemId}
            class={[
              ns.e('item'),
              ns.e('item-deuiaction'),
              ns.is('loading', c.state.buttonsState[itemId].loading),
            ]}
          >
            <el-button
              title={item.tooltip}
              size={btnSize.value}
              loading={c.state.buttonsState[itemId].loading}
              disabled={c.state.buttonsState[itemId].disabled}
              onClick={(e: MouseEvent): Promise<void> => handleClick(item, e)}
            >
              {btnContent(item)}
            </el-button>
          </div>
        );
      }
      if (item.itemType === 'ITEMS') {
        return (
          <el-menu
            mode='horizontal'
            class={[ns.e('menu')]}
            ellipsis={false}
            menu-trigger='hover'
          >
            {renderSubmenu(item)}
          </el-menu>
        );
      }
      return null;
    };

    return {
      c,
      btnSize,
      ns,
      handleClick,
      renderExtraButtons,
      renderToolbarItem,
    };
  },
  render() {
    const { state } = this.c;

    let content = null;
    if (state.isCreated) {
      content = [
        // 绘制最前方的额外按钮
        state.extraButtons.before?.length > 0 &&
          this.renderExtraButtons(state.extraButtons.before),
        this.modelData.detoolbarItems?.map((item, index) => {
          const toolbarItemNode = this.renderToolbarItem(item);
          // 绘制指定位置后的额外按钮
          if (state.extraButtons[index]?.length) {
            return [
              toolbarItemNode,
              this.renderExtraButtons(state.extraButtons[index]),
            ];
          }
          return toolbarItemNode;
        }),
        // 绘制最后方的额外按钮
        state.extraButtons.after?.length > 0 &&
          this.renderExtraButtons(state.extraButtons.after),
      ];
    }

    return (
      <iBizControlBase
        controller={this.c}
        class={[this.ns.m(state.viewMode.toLowerCase())]}
      >
        {content}
      </iBizControlBase>
    );
  },
});
